package com.ruibang.glass.quality.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.camunda.ProcessRuleChangeReq;
import com.ruibang.glass.common.domain.file.FileBusiness;
import com.ruibang.glass.quality.domain.req.QualityContactReq;
import com.ruibang.glass.quality.entity.QualityContact;
import com.ruibang.glass.quality.feign.CamundaApi;
import com.ruibang.glass.quality.feign.FileApi;
import com.ruibang.glass.quality.feign.PortalApi;
import com.ruibang.glass.quality.mapper.QualityContactMapper;
import com.ruibang.glass.quality.service.QualityContactService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.model.ResultBody;
import com.teaming.cloud.framework2.common.pojo.PageRequest;
import com.teaming.cloud.framework2.common.pojo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 品质联络单信息 服务实现类
 * </p>
 *
 * @author wujie
 * @since 2023-11-30
 */
@Service
@Slf4j
public class QualityContactServiceImpl extends ServiceImpl<QualityContactMapper, QualityContact> implements QualityContactService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private FileApi fileApi;

    @Autowired
    private PortalApi portalApi;

    @Autowired
    private CamundaApi camundaApi;

//    @Autowired
//    private RedisSingleService redisService;

    @Autowired
    private RedisSingleService redisService;

    @Override
    public void saveInfo(QualityContact qualityContact) {
        String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern(CommonConstant.DATE_FORMAT_YEAR_MONTH_UN_SEPARATE));
        String oldIssueCode = baseMapper.getMaxIssueCode();
        String issueCode  = "";
        if(StringUtils.isNotBlank(oldIssueCode)){
            long id = Long.parseLong(oldIssueCode);
            id = id + 1;
            issueCode = dateStr.concat(String.valueOf(id).substring(6));
        }else{
            issueCode = dateStr.concat("001");
        }
        if(StringUtils.isNotBlank(issueCode)){
            qualityContact.setIssueCode(issueCode);
            this.save(qualityContact);

            if(StringUtils.isNotBlank(qualityContact.getUserId())){
                //修改规则中的options
                ProcessRuleChangeReq changeReq = new ProcessRuleChangeReq();
                changeReq.setProcessDefinitionId(qualityContact.getProcessDefinitionId());
                changeReq.setProcessNodes(qualityContact.getProcessNodes());
                List<String> options = Arrays.asList(qualityContact.getUserId());
                changeReq.setOptions(JSON.toJSONString(options));
                camundaApi.changeProcessDefinitionRule(changeReq);
            }

            //更新文件对应业务Id
            if(CollectionUtils.isNotEmpty(qualityContact.getFileIds())){
                FileBusiness fileBusiness = new FileBusiness();
                fileBusiness.setFileIds(qualityContact.getFileIds());
                fileBusiness.setBusinessId(qualityContact.getContactId());
                fileApi.updateBusinessById(fileBusiness);
            }

            //发起流程
            BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
            instanceCreate.setBusinessKey(qualityContact.getContactId());
            instanceCreate.setMenuId(qualityContact.getMenuId());
            if(StringUtils.isNotBlank(qualityContact.getUserId())){
                Map<String, Object> variables = new HashMap<>();
                variables.put(Constants.PROCESS_INSTANCE_STARTER_USER_ID,qualityContact.getUserId());
                variables.put(Constants.PROCESS_INSTANCE_BUSINESS_KEY,qualityContact.getContactId());
                variables.put(Constants.PROCESS_INSTANCE_MENU_ID,qualityContact.getMenuId());
                instanceCreate.setVariables(variables);
            }
            commonService.startProcess(instanceCreate);
        }
    }

    @Override
    public void updateInfo(QualityContact qualityContact) {
        qualityContact.setUpdateTime(LocalDateTime.now());
        this.updateById(qualityContact);
        //更新文件信息
        if(CollectionUtils.isNotEmpty(qualityContact.getDeleteFileIds())){
            fileApi.deleteByFileIds(qualityContact.getDeleteFileIds());
        }

        //新增文件
        if(CollectionUtils.isNotEmpty(qualityContact.getFileIds())){
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setBusinessId(qualityContact.getContactId());
            fileBusiness.setFileIds(qualityContact.getFileIds());
            fileApi.updateBusinessById(fileBusiness);
        }
    }

    @Override
    public PageResult<QualityContact> queryPage(PageRequest<QualityContactReq> pageRequest) {
        final QualityContactReq param = pageRequest.getParam();
        final LambdaQueryWrapper<QualityContact> lambda = new QueryWrapper<QualityContact>().lambda();
        this.buildCondition(lambda,param);
        final IPage<QualityContact> page = this.page(new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize()), lambda);
        if(page!=null&&CollectionUtils.isNotEmpty(page.getRecords())){
            List<String> businessKeys = page.getRecords().stream().map(c->c.getContactId()).collect(Collectors.toList());

            Map<Object, Object> deptMap = redisService.hmget(RedisKey.DEPT_GROUP_TYPE);
            Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);


            Map<String, BpmProcessInstanceStatus> processMap = null;
            //获取业务流程状态
            ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
            if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
                processMap = resultBody.getData().stream().collect(Collectors.toMap(bp->bp.getBusinessKey(), bp->bp, (bp1, bp2) -> bp1));
            }
            for (QualityContact qualityContact : page.getRecords()) {
                if(processMap!=null && processMap.get(qualityContact.getContactId())!=null){
                    BpmProcessInstanceStatus process = processMap.get(qualityContact.getContactId());
                    qualityContact.setStatus(String.valueOf(process.getStatus()));
                    qualityContact.setProcessId(process.getProcessInstanceId());
                    qualityContact.setNodeName(process.getNodeName());
                    if (StringUtils.isNotBlank(process.getUserId())) {
                        if(process.getUserId().indexOf(CommonConstant.SpecialSign.COMMA.getName())!=-1){
                            String[] userIds= process.getUserId().split(CommonConstant.SpecialSign.COMMA.getName());
                            StringBuilder userName = new StringBuilder();
                            int size = userIds.length;
                            for (int i=0;i< size;i++) {
                                String name = userMap.get(userIds[i])==null?"":userMap.get(userIds[i]).toString();
                                if(i==size-1){
                                    userName.append(name);
                                }else{
                                    userName.append(name).append(CommonConstant.SpecialSign.COMMA.getName());
                                }
                            }
                            qualityContact.setApproveUserId(process.getUserId());
                            qualityContact.setApproveUserName(userName.toString());
                        }else{
                            qualityContact.setApproveUserId(process.getUserId());
                            qualityContact.setApproveUserName(userMap.get(process.getUserId())==null?"":userMap.get(process.getUserId()).toString());
                        }
                    }
                }

                if(deptMap!=null){
                    if(StringUtils.isNotBlank(qualityContact.getDeptId())){
                        qualityContact.setDeptName(deptMap.get(qualityContact.getDeptId())==null?"":deptMap.get(qualityContact.getDeptId()).toString());
                    }
                    if(StringUtils.isNotBlank(qualityContact.getReceiveDeptId())){
                        qualityContact.setReceiveDeptName(deptMap.get(qualityContact.getReceiveDeptId())==null?"":deptMap.get(qualityContact.getReceiveDeptId()).toString());
                    }
                }
                if(userMap!=null){
                    if(StringUtils.isNotEmpty(qualityContact.getUserId())){
                        qualityContact.setUserName(userMap.get(qualityContact.getUserId())==null?"":userMap.get(qualityContact.getUserId()).toString());
                    }
                    if(StringUtils.isNotEmpty(qualityContact.getUserId())){
                        qualityContact.setReceiveUserName(userMap.get(qualityContact.getReceiveUser())==null?"":userMap.get(qualityContact.getReceiveUser()).toString());
                    }
                    if(StringUtils.isNotEmpty(qualityContact.getUserId())){
                        qualityContact.setAffirmUserName(userMap.get(qualityContact.getAffirmUser())==null?"":userMap.get(qualityContact.getAffirmUser()).toString());
                    }
                }
            }
        }

        PageResult<QualityContact> pr = new PageResult(page);
        return pr;
    }

    @Override
    public List<QualityContact> queryQualityContacts(QualityContactReq contactReq) {
        final LambdaQueryWrapper<QualityContact> lambda = new QueryWrapper<QualityContact>().lambda();
        this.buildCondition(lambda,contactReq);
        return this.list(lambda);
    }

    @Override
    public QualityContact getDetail(String contactId) {
        QualityContact qualityContact = this.getById(contactId);
        if(qualityContact!=null){
           ResultBody<List<String>> resultBody = fileApi.getFileIdsByBusinessId(qualityContact.getContactId());
           if(resultBody!=null&&CollectionUtils.isNotEmpty(resultBody.getData())){
               qualityContact.setFileIds(resultBody.getData());
           }
        }
        return qualityContact;
    }

    /**
     * 构造查询条件
     * @param lambda
     * @param param
     */
    private void buildCondition(LambdaQueryWrapper<QualityContact> lambda, QualityContactReq param){
        if(null == param) return;
        if(!org.springframework.util.StringUtils.isEmpty(param.getContactId())){
            lambda.eq(QualityContact::getContactId, param.getContactId());
        }
        if(!org.springframework.util.StringUtils.isEmpty(param.getIssueCode())){
            lambda.eq(QualityContact::getIssueCode, param.getIssueCode());
        }
        if(!org.springframework.util.StringUtils.isEmpty(param.getDeptId())){
            lambda.eq(QualityContact::getDeptId, param.getDeptId());
        }
        if(!org.springframework.util.StringUtils.isEmpty(param.getUserId())){
            lambda.eq(QualityContact::getUserId, param.getUserId());
        }
        if(param.getStartTime()!=null&&param.getEndTime()!=null){
            lambda.ge(QualityContact::getIssueTime, param.getStartTime());
            lambda.le(QualityContact::getIssueTime, param.getEndTime());
        }
        if(!org.springframework.util.StringUtils.isEmpty(param.getContactItem())){
            lambda.eq(QualityContact::getContactItem, param.getContactItem());
        }
        lambda.orderBy(true,false, QualityContact::getIssueTime);
    }


    public static void main(String[] args) {
       List<String> list = new ArrayList<>();
       list.add("aa");
       list.add("bb");
        System.out.println(JSON.toJSON(list));
    }
}
